package util;
/**
 * 
 * @author ladjzero
 *
 * @param <T>
 */
public class CircularQueue<T> {
	private int size;
	private T[] elements;
	private int head;
	private int rear;
	
	@SuppressWarnings("unchecked")
	public CircularQueue(int size){
		this.size = size+1;	//because queue[rear] is null
		elements = (T[])new Object[size+1];
		head = 0;
		rear = 0;
	}
	
	public boolean empty(){
		if( rear == head )
			return true;
		else
			return false;
	}
	
	public boolean full(){
		if(rear == size-1){
			if( 0 == head )
				return true;
			else
				return false;
		}
		else if( rear+1 == head )
			return true;
		else
			return false;	
	}
	
	public T getNext(){
		if( empty() ){
			try {
				throw new Exception("Circular Queue is empty already.");
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		T element = elements[head];
		headMove();
		return element;
	}
	
	public boolean add(T element){
		if( full() ){
			try {
				throw new Exception("Circular Queue is full already.");
			} catch (Exception e) {
				e.printStackTrace();
			}
			return false;
		}
		elements[rear] = element;
		rearMove();
		return true;
	}
	
	private void headMove(){
		head++;
		if(head == size)
			head = 0;
	}
	private void rearMove(){
		rear++;
		if(rear == size)
			rear = 0;
	}
}
